/**
 *******************************************************************************
 * @FileName  : user_main.c
 * @Author    : GaoQiu
 * @CreateDate: 2020-05-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */
#include "user_main.h"
#include "utils/soft_uart.h"
#include "utils/mdc.h"
#include "user_main.h"
#include "utils/pool_buf.h"
#include "utils/msg.h"
#include "utils/stimer.h"
#include "utils/math.h"
#include "utils/heap.h"
#include "utils/lg_mem.h"

#include "libc/string.h"

#include "hci_transport/hci_tr_api.h"
#include "stack/controller/ll_api.h"
#include "stack/controller/bb_api.h"
#include "stack/hci_defs.h"
#include "stack/controller/lhci_api.h"

#include "bsp/bsp.h"

/*!< Heap Size */
#define APP_HEAP_MEM_SIZE      (30 * 1024)
static uint32_t heap[APP_HEAP_MEM_SIZE/sizeof(uint32_t)] = {0};

/*!< LED blink period Unit:ms */
#define APP_LED_EN              1
#define APP_LED_BLINK_PERIOD    1000 //Unit:ms

/*!< Enable White-list  */
#define APP_WL_EN               0
#define APP_WL_NUM              1

/*! Connection parameter configuration */
#define APP_MAX_MST_NUM         1
#define APP_MAX_SLV_NUM         1
#define APP_MAX_CONN_NUM        (APP_MAX_MST_NUM + APP_MAX_SLV_NUM)

/*! HCI config. */
const LhciConfig_t lhciCfg = {
	maxAclLen  : 251, /*!< max acl parameter length.  >= LL max ACL data length. */
	maxCmdLen  : 65, /*!< max cmd parameter length.   */
	maxEvtLen  : 65, /*!< max evt parameter length.   */

	numCmdBufs : 8,  /*!< max rx cmd buffer number.    */
	numAclBufs : 8,  /*!< max rx acl buffer number.    */
	numEvtBufs : 8,  /*!< max tx evt/acl buffer number.*/
};

/*! Link layer config. */
const LlCfg_t llCfg = {
	versNr    : LL_VER_BT_CORE_SPEC, /*!< BLE Core version.           */
	compId    : LL_COMPANY_ID,       /*!< Company ID.                 */
	subVersNr : LL_SUB_VERSION_NUM,  /*!< Implementation version.     */

	wlNum     : APP_WL_NUM,          /*!< White-list size.             */
	rlNum     : 1,                   /*!< Resolve list size.          */

	numAdvSet         : 0,
	extAdvDataLen     : 0,
	extScanRspDataLen : 0,
	advMargin         : 0,             /*!< unit:ms */

	maxMst    : APP_MAX_MST_NUM,     /*!< Max number of master connection. */
	maxSlv    : APP_MAX_SLV_NUM,     /*!< Max number of SLAVE connection. */
	maxAclLen : 251,                  /*!< Length of ACL data.         */
	numRxBufs : 16,                  /*!< Number of Rx buffer.        */
	numTxBufs : 16,                  /*!< Number of Tx buffer.        */
	localSCA  : 300,                 /*!< Local sleep clock accuracy. */

	mstMargin : 6,                   /*!< Master connection margin.Unit: 0.625ms */
	numMoreDat: 6,                   /*!< the max number of more data. Range: >1. */

	authPyldTimeoutEn: false,
};

/*! Application main control block. */
typedef struct{
	MdcTimer_t      timer;
	MdcTimer_t      termTimer;
	MdcHandlerId_t  handlerId;
}AppCb_t;

static AppCb_t appCb;

void APP_MsgHandler(MdcEventMask_t event, MdcMsgHdr_t *pMsg)
{
	if(pMsg)
	{
		switch(pMsg->event)
		{
		case APP_EVT_UPD_ADV_DATA:
			BSP_LedToggle(LED_BLUE_PIN);
			MDC_TimerStartMs(&appCb.timer, APP_LED_BLINK_PERIOD);
			break;

		case APP_EVT_DISCONN:
			break;

		default:
			break;
		}
	}

	if(event)
	{
	}
}

void APP_Init(void)
{
	appCb.handlerId = MDC_AddMsgHandler(APP_MsgHandler);
	appCb.timer.handlerId = appCb.handlerId;
	appCb.timer.msg.event = APP_EVT_UPD_ADV_DATA;
#if APP_LED_EN
	MDC_TimerStartMs(&appCb.timer, APP_LED_BLINK_PERIOD);
#endif
}

void Setup(void)
{
	/* memory initialization. */
	lg_mem_init();
	HeapInit((uint8_t *)&heap[0], APP_HEAP_MEM_SIZE);

	/* BSP initialization. */
	BSP_InitAllLed();

	/* Buffer pool allocate. */
	pool_desc_t pools[] ={
		{16,     16 },
		{32,     16 },
		{64,     16 },
		{128,    2  },
		{280,    4  },
	};
	PoolBufInit(pools, COUNTOF(pools));

	/* MDC system initialization. */
	MDC_Init();

	/* MDC Timer initialization. */
	MDC_TimerInit();

	/* Set MAC address. */
	uint8_t bdAddr[6] = {0x66, 0x66, 0x66, 0x66, 0x00, 0x00};
	GetConfigParam(CFG_PARAM_MAC_ADDR, bdAddr, 6);
	LL_SetBdAddr(bdAddr, BD_ADDR_LEN);

	/* LL initialization. */
	LL_Init(&llCfg);
	LL_MstInit();
	LL_SlvInit();
	BB_SetTxPower(BB_POWER_P3p01_dBm);

	/* HCI Configuration */
	LHCI_Init(&lhciCfg);

	/* HCI Transport. */
	HCI_TR_Init();

	/* Application initialization. */
	APP_Init();

#if APP_WL_EN
	/* Set White-list */
	LL_LE_AddDeviceToWhiteList(LL_ADDR_PUBLIC, addr0);
#endif
}

void Loop(void)
{
	HCI_TR_TaskStart();

	MDC_Start();
}

